diffeq_errors.f90 Source File


Source Code

module diffeq_errors
    !! A collection of routines for handling errors in the DIFFEQ library.
    use iso_fortran_env
    use ferror
    implicit none
    
! ------------------------------------------------------------------------------
    ! Error Flags
    integer(int32), parameter :: DIFFEQ_MEMORY_ALLOCATION_ERROR = 10000
    integer(int32), parameter :: DIFFEQ_NULL_POINTER_ERROR = 10001
    integer(int32), parameter :: DIFFEQ_MATRIX_SIZE_ERROR = 10002
    integer(int32), parameter :: DIFFEQ_ARRAY_SIZE_ERROR = 10003
    integer(int32), parameter :: DIFFEQ_INVALID_INPUT_ERROR = 10004
    integer(int32), parameter :: DIFFEQ_MISSING_ARGUMENT_ERROR = 10005
    integer(int32), parameter :: DIFFEQ_STEP_SIZE_TOO_SMALL_ERROR = 10006
    integer(int32), parameter :: DIFFEQ_ITERATION_COUNT_EXCEEDED_ERROR = 10007
    integer(int32), parameter :: DIFFEQ_INVALID_OPERATION_ERROR = 10008

! ------------------------------------------------------------------------------
contains
! ------------------------------------------------------------------------------
subroutine report_memory_error(err, fcn, flag)
    !! Reports a memory error.
    class(errors), intent(inout) :: err
        !! The error handling object.
    character(len = *), intent(in) :: fcn
        !! The name of the function or subroutine in which the error occurred.
    integer(int32), intent(in) :: flag
        !! The memory status flag.

    ! Local Variables
    character(len = 256) :: msg

    ! Process
    write(msg, 100) "Memory allocation error flag ", flag, "."
    call err%report_error(fcn, trim(msg), DIFFEQ_MEMORY_ALLOCATION_ERROR)

    ! Formatting
100 format(A, I0, A)
end subroutine

! ------------------------------------------------------------------------------
subroutine report_matrix_size_error(err, fcn, varname, exprow, expcol, &
    actrow, actcol)
    !! Reports a matrix size error.
    class(errors), intent(inout) :: err
        !! The error handling object.
    character(len = *), intent(in) :: fcn
        !! The name of the function or subroutine in which the error occurred.
    character(len = *), intent(in) :: varname
        !! The offending variable name.
    integer(int32), intent(in) :: exprow
        !! The expected number of rows.
    integer(int32), intent(in) :: expcol
        !! The expected number of columns.
    integer(int32), intent(in) :: actrow
        !! The actual number of rows.
    integer(int32), intent(in) :: actcol
        !! The actual number of columns.

    ! Local Variables
    character(len = 256) :: msg

    ! Process
    write(msg, 100) "The matrix " // varname // " was expected to be (", &
        exprow, "-by-", expcol, "), but was found to be (", actrow, "-by-", &
        actcol, ")."
    call err%report_error(fcn, trim(msg), DIFFEQ_MATRIX_SIZE_ERROR)

    ! Formatting
100 format(A, I0, A, I0, A, I0, A, I0, A)
end subroutine

! ------------------------------------------------------------------------------
subroutine report_min_array_size_not_met(err, fcn, varname, minsize, actsize)
    !! Reports an error where the minimum array size was not met.
    class(errors), intent(inout) :: err
        !! The error handling object.
    character(len = *), intent(in) :: fcn
        !! The name of the function or subroutine in which the error occurred.
    character(len = *), intent(in) :: varname
        !! The offending variable name.
    integer(int32), intent(in) :: minsize
        !! The minimum size of the array.
    integer(int32), intent(in) :: actsize
        !! The actual size of the array.

    ! Local Variables
    character(len = 256) :: errmsg

    ! Process
    write(errmsg, 100) "Array " // varname // " must be at least of size ", &
        minsize, ", but was found to be of size ", actsize, "."
    call err%report_error(fcn, trim(errmsg), DIFFEQ_ARRAY_SIZE_ERROR)

    ! Formatting
100 format(A, I0, A, I0, A)
end subroutine

! ------------------------------------------------------------------------------
subroutine report_missing_ode(err, fcn)
    !! Reports a missing ODE routine.
    class(errors), intent(inout) :: err
        !! The error handling object.
    character(len = *), intent(in) :: fcn
        !! The name of the function or subroutine in which the error occurred.

    ! Process
    call err%report_error(fcn, "No ODE routine has been supplied.", &
        DIFFEQ_NULL_POINTER_ERROR)
    return
end subroutine

! ------------------------------------------------------------------------------
subroutine report_array_size_error(err, fcn, varname, expsize, actsize)
    !! Reports an array size error.
    class(errors), intent(inout) :: err
        !! The error handling object.
    character(len = *), intent(in) :: fcn
        !! The name of the function or subroutine in which the error occurred.
    character(len = *), intent(in) :: varname
        !! The offending variable name.
    integer(int32), intent(in) :: expsize
        !! The expected size of the array.
    integer(int32), intent(in) :: actsize
        !! The actual size of the array.

    ! Local Variables
    character(len = 256) :: msg

    ! Process
    write(msg, 100) "Array " // varname // " was expected to be of size ", &
        expsize, ", but was found to be of size ", actsize, "."
    call err%report_error(fcn, trim(msg), DIFFEQ_ARRAY_SIZE_ERROR)

    ! Formatting
100 format(A, I0, A, I0, A)
end subroutine

! ------------------------------------------------------------------------------
subroutine report_missing_argument(err, fcn, arg)
    !! Reports a missing argument error.
    class(errors), intent(inout) :: err
        !! The error handling object.
    character(len = *), intent(in) :: fcn
        !! The name of the function or subroutine in which the error occurred.
    character(len = *), intent(in) :: arg
        !! The name of the argument.

    ! Process
    call err%report_error(fcn, "Argument " // arg // " was missing.", &
        DIFFEQ_MISSING_ARGUMENT_ERROR)
end subroutine

! ------------------------------------------------------------------------------
subroutine report_step_size_too_small(err, fcn, x, h)
    !! Reports an error when the step size becomes too small.
    class(errors), intent(inout) :: err
        !! The error handling object.
    character(len = *), intent(in) :: fcn
        !! The name of the function or subroutine in which the error occurred.
    real(real64), intent(in) :: x
        !! The value of the independent variable at which the step size error
        !! occurred.
    real(real64), intent(in) :: h
        !! The step size value.

    ! Process
    character(len = 256) :: msg
    write(msg, 100) "A step size of ", h, " was encountered at x = ", x, &
        ", and is too small to continue integration."
    call err%report_error(fcn, trim(msg), DIFFEQ_STEP_SIZE_TOO_SMALL_ERROR)

    ! Formatting
100 format(A, EN0.3, A, EN0.3, A)
end subroutine

! ------------------------------------------------------------------------------
subroutine report_excessive_iterations(err, fcn, n, x)
    !! Reports an error when excessive iterations have been made.
    class(errors), intent(inout) :: err
        !! The error handling object.
    character(len = *), intent(in) :: fcn
        !! The name of the function or subroutine in which the error occurred.
    integer(int32), intent(in) :: n
        !! The number of iterations.
    real(real64), intent(in) :: x
        !! The value of the independent variable at which the error occurred.

    ! Process
    character(len = 256) :: msg
    write(msg, 100) "The allowable iteration count was exceeded (iteration ", &
        n, ") at x = ", x, "."
    call err%report_error(fcn, trim(msg), DIFFEQ_ITERATION_COUNT_EXCEEDED_ERROR)

    ! Formatting
100 format(A, I0, A, EN0.3, A)
end subroutine

! ------------------------------------------------------------------------------
subroutine report_excessive_integration_steps(err, fcn, n, x)
    !! Reports an error when an excessive  amount integration steps have been 
    !! taken.
    class(errors), intent(inout) :: err
        !! The error handling object.
    character(len = *), intent(in) :: fcn
        !! The name of the function or subroutine in which the error occurred.
    integer(int32), intent(in) :: n
        !! The number of integration steps.
    real(real64), intent(in) :: x
        !! The value of the independent variable at which the error occurred.

    ! Process
    character(len = 256) :: msg
    write(msg, 100) &
        "The allowable number of integration steps was exceeded (step ", &
        n, " at x = ", x, "."

    ! Formatting
100 format(A, I0, A, EN0.3, A)
end subroutine

! ------------------------------------------------------------------------------
end module